


module UART_Send(
	input				clk,
	input				rst,
	
	output reg		uart_send,
	
	input				send_req,
	output			send_ack,
	
	input[7:0]		send_data
);

localparam	S_IDLE			= 0;
localparam	S_STAR  			= 1;
localparam	S_DATA			= 2;
localparam	S_STOP			= 3;  //停止位
localparam	S_ACK				= 4;

 
localparam 	CYCLE				= 50 * 1000_000 / 115200;



reg[2:0]		state,next_state;

reg[23:0]	clk_cnt;

reg[7:0]		data_latch;

reg[3:0]		data_cnt;

assign send_ack = (state == S_ACK) ? 1'b1 : 1'b0;


always@(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		state <= S_IDLE;
	else
		state <= next_state;
end


always@(*)
begin
	case(state)
	S_IDLE:
		if(send_req == 1'b1)
			next_state <= S_STAR;
		else
			next_state <= S_IDLE;
	S_STAR:
		if(clk_cnt == CYCLE)
			next_state <= S_DATA;
		else
			next_state <= S_STAR;
	S_DATA:
		if(data_cnt == 'd7 && clk_cnt == CYCLE)
			next_state <= S_STOP;
		else
			next_state <= S_DATA;
	S_STOP:
		if(clk_cnt == CYCLE)
			next_state <= S_ACK;
		else
			next_state <= S_STOP;
	S_ACK:
		next_state <= S_IDLE;
	default:
		next_state <= S_IDLE;
	endcase

end









always@(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		uart_send <= 1'b1;
	else if(state == S_IDLE)
		uart_send <= 1'b1;
	else if(state == S_STAR)
		uart_send <= 1'b0;
	else if(state == S_DATA)
		uart_send <= data_latch[0];
	else if(state == S_STOP)
		uart_send <=  1'b1;
	else
		uart_send <= uart_send;
end


always@(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		clk_cnt <= 'd0;
	else if(state == S_DATA || state == S_STAR || state == S_STOP)
		if(clk_cnt == CYCLE)
			clk_cnt <= 'd0;
		else
			clk_cnt <= clk_cnt + 1'b1;
	else
		clk_cnt <= 'd0;
end


always@(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		data_latch <= 'd0;
	else if(state == S_IDLE && send_req == 1'b1)
		data_latch <= send_data;
	else if(state == S_DATA)
		if(clk_cnt == CYCLE)
			data_latch <= {data_latch[0],data_latch[7:1]};
		else
			data_latch <= data_latch;
	else
		data_latch <= data_latch;
end



always@(posedge clk or negedge rst)
begin
	if(rst == 1'b0)
		data_cnt <= 'd0;
	else if(state == S_DATA)
		if(clk_cnt == CYCLE)
			data_cnt <= data_cnt + 1'b1;
		else
			data_cnt <= data_cnt;
	else
		data_cnt <= 'd0;
end






endmodule 